package Utils;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigDecimal;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.media.ExifInterface;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.netease.log.NTLog;
import com.netease.pkgRelated.XoneConsts;
import com.netease.xone.R;

public class XoneUtil {

    public static String nullStr(String str) {
        if (TextUtils.isEmpty(str))
            return null;

        return str;
    }

    /**
     * dip转pixel
     * 
     * @param context
     * @param dipValue
     * @return
     */
    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    /**
     * pixel转dip
     * 
     * @param context
     * @param pxValue
     * @return
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    public static boolean saveObjectToFile(Context context, Object o,
            String filename) {
        if (context == null) {
            return false;
        }
        try {
            FileOutputStream fos = context.openFileOutput(filename,
                    Context.MODE_PRIVATE);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(o);
            oos.flush();
            oos.close();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static Object readObjectFromFile(Context context, String filename) {
        if (context == null) {
            return null;
        }
        try {
            FileInputStream fis = context.openFileInput(filename);
            ObjectInputStream ois = new ObjectInputStream(fis);
            return ois.readObject();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static int getRotateDegree(Context context, Uri uri) {
        if (uri == null) {
            return 0;
        }
        String file = uri.getPath();
        if (TextUtils.isEmpty(file)) {
            return 0;
        }
        ExifInterface exif;
        try {
            exif = new ExifInterface(file);
        } catch (IOException e) {
            e.printStackTrace();
            return 0;
        }
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_UNDEFINED);
        int degree = 0;
        if (orientation != ExifInterface.ORIENTATION_UNDEFINED) {
            // We only recognize a subset of orientation tag values.
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
                default:
                    degree = 0;
                    break;
            }
        } else {
            ContentResolver cr = context.getContentResolver();
            Cursor cursor = cr.query(uri, null, null, null, null);
            if (cursor != null) {
                cursor.moveToFirst();
                String orientationDb = cursor.getString(cursor
                        .getColumnIndex("orientation"));
                cursor.close();
                if (!TextUtils.isEmpty(orientationDb)) {
                    degree = Integer.parseInt(orientationDb);
                }
            }
        }
        Log.d("getRotateDegree", "getRotateDegree, file:" + file + ",degree:"
                + degree);
        return degree;
    }

    public static String swVersion = null;

    public static String getSwVersion(Context context) {
        if (swVersion == null || swVersion.length() == 0)
            swVersion = getApplicationMetaInfo(context, "VERSION");
        ;
        return swVersion;
    }

    public static String getApplicationMetaInfo(Context context, String metaName) {
        PackageManager pm = context.getPackageManager();
        ApplicationInfo info;
        try {
            info = pm.getApplicationInfo(context.getPackageName(), 128);
            if (info != null && info.metaData != null) {
                return info.metaData.getString(metaName);
            } else {
                return null;
            }
        } catch (NameNotFoundException e) {
            return null;
        }

    }

    public static String getNumberVersion(Context context) {
        if (null == context) {
            NTLog.w("Util", "invalid input when calling getClientVersion()");
            return "";
        }
        String clientVer = "0.0.0";
        try {
            clientVer = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0).versionName;
        } catch (NameNotFoundException e) {
            NTLog.w("Util", "failed to get version");
        }
        if (null != clientVer) {
            clientVer = clientVer.trim();
        }
        return clientVer;
    }

    /** 获取渠道id */
    private static final String DEFAULT_CHANNEL_ID = "netease";

    public static String getAppChannelID(Context context) {
        InputStream is = context.getResources()
                .openRawResource(context.getResources().getIdentifier("channel", "raw", context.getPackageName()));
        if (is != null) {
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(
                        is, "GB2312"));
                String line = in.readLine();
                if (line != null) {
                    return line.trim();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return DEFAULT_CHANNEL_ID;
    }

    // 判断邮件地址是否合法
    public static boolean isValidAddress(String address) {
        // Note: Some email provider may violate the standard, so here we only
        // check that
        // address consists of two part that are separated by '@', and domain
        // part contains
        // at least one '.'.
        int len = address.length();
        int firstAt = address.indexOf('@');
        int lastAt = address.lastIndexOf('@');
        int firstDot = address.indexOf('.', lastAt + 1);
        int lastDot = address.lastIndexOf('.');
        return firstAt > 0 && firstAt == lastAt && lastAt + 1 < firstDot
                && firstDot <= lastDot && lastDot < len - 1;
    }

    // 获取编码格式
    public static String getCharset(String ContentType) {
        if (ContentType == null) {
            return "UTF-8";
        } else {
            int i = ContentType.indexOf("=");
            String charset = null;
            if (i < 0) {
                charset = "UTF-8";
            } else {
                charset = ContentType.substring(i + 1);
            }
            return charset;
        }
    }
    //判断手机号码合法性
    public static boolean isValidatePhoneNum(String phoneNum) {
        return phoneNum.matches("[0-9]{11}");
    }
    /**一个汉字算2个字符*/
    public static int getNicknameLen(String nickname) {
        int len = 0;
        char[] chars = nickname.toCharArray();
        for (char c : chars) {
            String s = Character.toString(c);
            if (s.matches("[\\u4E00-\\u9FA5]")) {
                len += 2;
            } else {
                len++;
            }
        }
        return len;
    }
    
    public static boolean isNicknameContainsSpecialChar(String nickname) {
        boolean result = false;
        Pattern pattern = Pattern.compile("[^a-zA-Z0-9_\\-\\u4E00-\\u9FA5]");
        Matcher matcher = pattern.matcher(nickname);
        if (matcher.find()) {
            result = true;
        }
        return result;
    }
    
    /**
     * 检查是否包含该APP
     * @param context
     * @param packageName App包名
     * @return
     */
    public static boolean hasApp(Context context, String packageName) {
        if (packageName == null || "".equals(packageName)) {
            return false;
        }
        try {
            PackageInfo pi = context.getPackageManager().getPackageInfo(packageName,
                    PackageManager.GET_ACTIVITIES);
            if(pi == null)return false;
            Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
            resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            resolveIntent.setPackage(pi.packageName);
            List<ResolveInfo> apps = context.getPackageManager().queryIntentActivities(
                    resolveIntent, 0);
            ResolveInfo ri = apps.iterator().next();
            if(ri == null)return false;
            return true;
        } catch (NameNotFoundException e) {
            return false;
        }
    }
    /**
     * 根据包名启动一个外部App。
     * 若该app已经安装且启动成功返回true，否则返回false。
     * @param context
     * @param packageName App包名
     * @return
     */
    public static boolean startOtherApp(Context context, String packageName) {
        if (packageName == null || "".equals(packageName)) {
            return false;
        }
        try {
            PackageInfo pi = context.getPackageManager().getPackageInfo(packageName,
                    PackageManager.GET_ACTIVITIES);
            if(pi == null)return false;
            Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
            resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            resolveIntent.setPackage(pi.packageName);
            List<ResolveInfo> apps = context.getPackageManager().queryIntentActivities(
                    resolveIntent, 0);
            ResolveInfo ri = apps.iterator().next();
            if(ri == null)return false;
            String className = ri.activityInfo.name;
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            ComponentName cn = new ComponentName(packageName, className);
            intent.setComponent(cn);
            context.startActivity(intent);
            return true;
        } catch (NameNotFoundException e) {
            return false;
        }
    }
    
    private final static long SIZE_KB = 1024;
    private final static long SIZE_MB = SIZE_KB * 1024;
    private final static long SIZE_GB = SIZE_MB * 1024;
    private final static long SIZE_TB = SIZE_GB * 1024;
    
    private final static long SIZE_KB_X = 1000;
    private final static long SIZE_MB_X = SIZE_KB * 1000;
    private final static long SIZE_GB_X = SIZE_MB * 1000;
    private final static long SIZE_TB_X = SIZE_GB * 1000;
    
    public final static int SIZE_UINT_DEFAULT = -1;
    public final static int SIZE_UINT_B = 0;
    public final static int SIZE_UINT_KB = 1;
    public final static int SIZE_UINT_MB = 2;
    public final static int SIZE_UINT_GB = 3;
    public final static int SIZE_UINT_TB = 4;
    public static String getSizeStr(long size, int num, int unit) {
        if(size <= 0)return "0B";
        StringBuffer sb = new StringBuffer("");
        final Float s = getSize(size, num, unit);
        if (unit == SIZE_UINT_B) {
            sb.append(s.intValue()).append("B");
        } else if (unit == SIZE_UINT_KB) {
            sb.append(s.intValue()).append("KB");
        } else if (unit == SIZE_UINT_MB) {
            sb.append(s).append("MB");
        } else if (unit == SIZE_UINT_GB) {
            sb.append(s).append("GB");
        } else if (unit == SIZE_UINT_TB) {
            sb.append(s).append("TB");
        } else {
            if (size < SIZE_KB_X) {
                sb.append(s.intValue()).append("B"); 
            } else if (size < SIZE_MB_X) {
                sb.append(s.intValue()).append("KB");
            } else if (size < SIZE_GB_X) {
                sb.append(s.intValue()).append("MB");
            } else if (size < SIZE_TB_X) {
                sb.append(s).append("GB"); 
            } else {
                sb.append(s).append("TB"); 
            }
        }       
        
        return sb.toString();
    }
    
    public static String getSizeStrNoB(long size, int num, int unit) {
        StringBuffer sb = new StringBuffer(size < 0 ? "-" : "");
        final Float s = getSize(size, num, unit);
        
        if (unit == SIZE_UINT_B) {
            sb.append(s.intValue()).append("B");
        } else if (unit == SIZE_UINT_KB) {
            sb.append(s.intValue()).append("K");
        } else if (unit == SIZE_UINT_MB) {
            sb.append(s).append("M");
        } else if (unit == SIZE_UINT_GB) {
            sb.append(s).append("G");
        } else if (unit == SIZE_UINT_TB) {
            sb.append(s).append("T");
        } else {
            if (size < SIZE_KB_X) {
                sb.append(s.intValue()).append("B"); 
            } else if (size < SIZE_MB_X) {
                sb.append(s.intValue()).append("K");
            } else if (size < SIZE_GB_X) {
                sb.append(s.intValue()).append("M");
            } else if (size < SIZE_TB_X) {
                sb.append(s).append("G"); 
            } else {
                sb.append(s).append("T"); 
            }
        }       
        
        return sb.toString();
    }
    public static float getSize(long size, int num, int unit) {
        double s = size;
        if (unit == SIZE_UINT_B) {
            return size;
        } else if (unit == SIZE_UINT_KB) {
            return formatDoubleNum((s /= SIZE_KB), num);
        } else if (unit == SIZE_UINT_MB) {
            return formatDoubleNum((s /= SIZE_MB), num);
        } else if (unit == SIZE_UINT_GB) {
            return formatDoubleNum((s /= SIZE_GB), num);
        } else if (unit == SIZE_UINT_TB) {
            return formatDoubleNum((s /= SIZE_TB), num);
        } else {
            if (size < SIZE_KB_X) {
                return size;
            } else if (size < SIZE_MB_X) {
                return formatDoubleNum((s /= SIZE_KB), num);
            } else if (size < SIZE_GB_X) {
                return formatDoubleNum((s /= SIZE_MB), num);
            } else if (size < SIZE_TB_X) {
                return formatDoubleNum((s /= SIZE_GB), num);
            } else {
                return formatDoubleNum((s /= SIZE_TB), num);
            }
        }
    }
    /**
     * 获取小数点位数
     * @param d 原来数据
     * @param num 小数点位数
     * @return 
     */
    public static Float formatDoubleNum(double d, int num){
        BigDecimal bd = new BigDecimal(d); 
        bd = bd.setScale (num, BigDecimal.ROUND_HALF_UP); 
        return bd.floatValue();
    }
    
    /**
     * 判断一个应用是否在前台
     * @param Context
     */
    public static boolean isTopActivity(Context context){  
        ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo>  tasksInfo = am.getRunningTasks(1);  
        if(tasksInfo.size() > 0){  
            //应用程序位于堆栈的顶层  
            if(context.getPackageName().equals(tasksInfo.get(0).topActivity.getPackageName())){  
                return true;  
            }  
        }  
        return false;  
    } 
    /**
     * 根据用户类型转换成要显示的字串
     * @param Context
     * @param type
     */
    public static String userTypeToString(Context context ,int type){
        if(context == null)
            return null;
        
        String typeStr = null;
        int resId = R.string.acc_type_usr;
        switch(type){
            case XoneConsts.ACCOUNT_TYPE.Urs:
                resId = R.string.acc_type_usr;
                break;
            case XoneConsts.ACCOUNT_TYPE.Tencent:
                resId = R.string.acc_type_tencent;
                break;
            case XoneConsts.ACCOUNT_TYPE.Sina:
                resId = R.string.acc_type_sina;
                break;
            case XoneConsts.ACCOUNT_TYPE.Renren:
                resId = R.string.acc_type_renren;
                break;
            case XoneConsts.ACCOUNT_TYPE.Phone:
                resId = R.string.acc_type_phone;
                break;
        }
        typeStr = context.getResources().getString(resId);
        return typeStr;
    }
}
